﻿using Microsoft.SharePoint;
using Navicon.SP.Common.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PopulateListsFromExcel
{
   public class SPListItemsIndexator
    {
        /// <summary>Кэшурем элементы списков в Dictionary. ключем выступает значение поля, a value - элемент списка, у которого в определенном поле содержится это самое значение. Как правилно, речь идет о поле "NTV_ID"
        /// </summary>
        public static Dictionary<Int32, SPListItem> CreateIndices(SPWeb web, SPList list, string fieldName)
        {
            Dictionary<Int32, SPListItem> indices = new Dictionary<Int32, SPListItem>();
            SPQuery query = new SPQuery();

            query.ViewFields = UtilityQuery.BuildViewFieldsXml("ID", fieldName);

            SPListItemCollection listItems = list.GetItems(query);
            if (listItems.Count > 0)
            {
                foreach (SPListItem spListItem in listItems)
                {
                    String fieldValue = Convert.ToString(spListItem[fieldName]);
                    if (String.IsNullOrEmpty(fieldValue))
                    {
                        continue;
                    }
                    try
                    {
                        Int32 hashValue = GetHashValue(fieldValue);
                        if (indices.ContainsKey(hashValue))
                        {
                            Console.WriteLine(
                                " В кэше уже содержится элемент списка с ID={0} и field value = {1}. FieldName={2}." +
                                " Вы пытаетесь добавить элемент с ID={3}, field value = {4} список {5}",
                                indices[hashValue].ID, fieldValue, fieldName,
                                spListItem.ID,
                                indices[hashValue][fieldName],
                                list.Title);

                        }
                        else
                        {
                            indices.Add(hashValue, spListItem);
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(String.Format("При формировании индексов для списка {0} была обнаружена ошибка. Текст ошибки: {1}",
                                fieldName, ex.Message));
                    }
                }
            }

            return indices;
        }

        public static Int32 GetHashValue(String value)
        {
            MD5 md5 = MD5.Create();
            Byte[] fullHash = md5.ComputeHash(Encoding.UTF8.GetBytes(value));
            Byte[] partHash = { fullHash[0], fullHash[1], fullHash[2], fullHash[3] };
            return BitConverter.ToInt32(partHash, 0);
        }

        public static SPListItem GetItemFromCache(Dictionary<Int32, SPListItem> cache, String fieldName, String fieldValue)
        {
            SPListItem item = null;
            Int32 hashValue = GetHashValue(fieldValue);

            if (cache.ContainsKey(hashValue))
            {
                return cache[hashValue];
            }

            return item;
        }

        public static object GetLookupValueFromCache(Dictionary<Int32, SPListItem> cachesList, String fieldName, String fieldValue)
        {
            SPFieldLookupValue lookupValue = null;
            if (fieldValue.Contains("##"))
            { //Мультилукап
                string[] fieldValues = fieldValue.Split(new string[] { "##" }, StringSplitOptions.RemoveEmptyEntries);
                SPFieldLookupValueCollection lookupValues = new SPFieldLookupValueCollection();

                foreach (string fieldValueAsStrig in fieldValues)
                {
                    SPListItem listItem = GetItemFromCache(cachesList, fieldName, fieldValueAsStrig);
                    if (listItem != null)
                    {
                        lookupValue = new SPFieldLookupValue(Convert.ToInt32(listItem["ID"]), fieldValueAsStrig);
                        lookupValues.Add(lookupValue);
                    }
                }
                return lookupValues;
            }
            else
            {// Одиночный лукап
                SPListItem item = GetItemFromCache(cachesList, fieldName, fieldValue);
                if (item != null)
                {
                    lookupValue = new SPFieldLookupValue(Convert.ToInt32(item["ID"]), fieldValue);
                }
                return lookupValue;
            }
            
        }
    }
}
